﻿#!/usr/bin/env python
# -*- coding: utf-8 -*-
# KonomeBot developed by Farseerfc,irolar
#if you would like to join in the develop, please twitter @irolar
#db_entity, entities for db access. API: http://code.google.com/appengine/docs/python/datastore/overview.html

from datetime import datetime
from google.appengine.ext import db
from google.appengine.api import users

class db_user(db.Model):
    jid = db.StringProperty()        # jid: Jabber IDentifier, such as farseerfc@gmail.com
    name = db.StringProperty()       # name: user defined name in Konobot, unique
    lang = db.StringProperty()
    reg_ts = db.DateTimeProperty()   # reg_ts: register time stamp
    last_ts = db.DateTimeProperty()  # last_ts: last time stamp when send command

class db_history(db.Model):
    jid = db.StringProperty()
    cmd = db.StringProperty()
    ts = db.DateTimeProperty()
    index = db.IntegerProperty()
    
class db_stock(db.Model):
    jid = db.StringProperty()
    stock = db.StringProperty()
    ts = db.DateTimeProperty()
    index = db.IntegerProperty()

def his_comp(his1,his2):
    c = cmp(his1.ts,his2.ts)
    if c != 0 : return c
    c = cmp(his1.index,his2.index)
    if c != 0 : return c
    c = cmp(his1.jid,his2.jid)
    if c != 0 : return c
    c = cmp(his1.cmd,his2.cmd)
    return c
def sto_comp(sto1,sto2):
    c = cmp(sto1.ts,sto2.ts)
    if c != 0 : return c
    c = cmp(sto1.index,sto2.index)
    if c != 0 : return c
    c = cmp(sto1.jid,sto2.jid)
    if c != 0 : return c
    c = cmp(sto1.stock,sto2.stock)
    return c
class User(object):
    '''
    Define a db interface for user
    '''
    def __init__(self,jid) :
        jid_list =  [ str(jid) ]
        result = db.GqlQuery('SELECT * FROM db_user WHERE jid IN :1', jid_list )
        if result.count() == 1 :
            self.db = result.get() 	        # if user already exists, use it and return
        elif (result.count() > 1) :           # if user exists for multiply instances
            for user in result.fetch(result.count()) :    #     delete all of them
                user.delete()
        else:
            str_jid = str(jid)          # else , create a new user
            name = jid.node
            now = datetime.now()
            self.db = db_user(jid = str_jid,name=jid.node,reg_ts=now,last_ts=now)
            self.db.put()
    def add_history(self,cmd):
        history = db_history(jid=self.db.jid,cmd = cmd,ts=datetime.now(),index = self.get_history_count())
        history.put()
        self.db.last_ts = datetime.now()
        self.db.put()
    def get_history(self):
        result = db.GqlQuery('SELECT * FROM db_history WHERE jid IN :1',[self.db.jid])
        his_list = result.fetch(result.count())
        his_list.sort(his_comp)
        return his_list
    def get_history_count(self):
        result = db.GqlQuery('SELECT * FROM db_history WHERE jid IN :1',[self.db.jid])
        return result.count()
    def get_history_by_index(self,index):
        result = self.get_history()
        for his in result:
            if his.index == index:
                return his
        return None
    def clear_history(self):
        result = db.GqlQuery('SELECT * FROM db_history WHERE jid IN :1',[self.db.jid])
        for his in result.fetch(self.get_history_count()):
            his.delete()

    def add_stock(self,stock):
        stock = db_stock(jid=self.db.jid,stock = stock,ts=datetime.now(),index = self.get_stock_count())
        stock.put()
        self.db.last_ts = datetime.now()
        self.db.put()
    def get_stock(self):
        result = db.GqlQuery('SELECT * FROM db_stock WHERE jid IN :1',[self.db.jid])
        sto_list = result.fetch(result.count())
        sto_list.sort(sto_comp)
        return sto_list
    def get_stockpure(self):
        result = db.GqlQuery('SELECT * FROM db_stock WHERE jid IN :1',[self.db.jid])
        sto_list = result.fetch(result.count())
        sto_list.sort(sto_comp)
        temp=[i.stock.encode('utf8') for i in sto_list]
        return temp
    def get_stock_count(self):
        result = db.GqlQuery('SELECT * FROM db_stock WHERE jid IN :1',[self.db.jid])
        return result.count()
    def get_stock_by_index(self,index):
        result = self.get_stock()
        for sto in result:
            if sto.index == index:
                return sto
        return None
    def clear_stock(self):
        result = db.GqlQuery('SELECT * FROM db_stock WHERE jid IN :1',[self.db.jid])
        for sto in result.fetch(self.get_stock_count()):
            sto.delete()


class Jid(object):
    '''
       as defined in http://tools.ietf.org/html/rfc3920
       Jid is in form node@sub.domain/resource
       where resource is omitted
    '''
    def __init__(self,sender):
        at_split = sender.split('@')
        self.node = at_split[0]
        slash_split = at_split[1].split('/')
        self.domain = slash_split[0]
        self.resource = slash_split[1]
    def __str__(self):
        return '%s@%s' %(self.node,self.domain)
    def __cmp__(self,other):
     		return cmp(str(self),str(other))
